/**
 * 诗人3D角色管理器
 * 专门处理诗人3D模型的加载、切换和动画控制
 */

import * as THREE from 'three';
import { ModelLoader, AnimationController } from './ModelLoader.js';
import { getPoetModelConfig, hasPoetModel, getDefaultPoetModelConfig } from './config/poet-models-config.js';
import { SCENE_TYPES } from './config/immersive-scenes-config.js';
import { ProgressManager } from './ProgressManager.js';

export class Poet3DCharacter {
    constructor(scene, options = {}) {
        this.scene = scene;
        this.options = {
            enablePreloading: options.enablePreloading !== false,
            enableAnimations: options.enableAnimations !== false,
            enableLighting: options.enableLighting !== false,
            ...options
        };
        
        // 进度管理器（可选，如果未提供则创建默认实例）
        this.progressManager = options.progressManager || new ProgressManager();
        
        this.modelLoader = new ModelLoader();
        this.currentPoetId = null;
        this.currentModel = null;
        this.currentAnimationController = null;
        
        // 模型缓存
        this.modelCache = new Map();
        this.loadingPromises = new Map();
        
        // 场景元素
        this.characterGroup = new THREE.Group();
        this.characterGroup.name = 'poet-character';
        this.scene.add(this.characterGroup);
        
        // 光照系统
        this.lightingGroup = new THREE.Group();
        this.lightingGroup.name = 'poet-lighting';
        this.scene.add(this.lightingGroup);
        
        this.clock = new THREE.Clock();
        
        console.log('诗人3D角色管理器初始化完成');
    }

    /**
     * 切换到指定诗人
     * @param {string} poetId - 诗人ID
     * @param {Object} options - 切换选项
     */
    async switchToPoet(poetId, options = {}) {
        try {
            console.log(`开始切换到诗人: ${poetId}`);
            
            // 检查是否由外部控制进度管理（如PoetSelector）
            const externalProgressControl = options.externalProgressControl || false;
            
            // 如果不是外部控制，则启动进度管理
            if (!externalProgressControl) {
                this.progressManager.startLoading();
                this.progressManager.updateProgress(10, `开始切换到诗人 ${poetId}...`);
            }
            
            // 检查是否有该诗人的模型配置
            if (!hasPoetModel(poetId)) {
                console.warn(`诗人 ${poetId} 没有3D模型配置，使用默认配置`);
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(20, `诗人 ${poetId} 使用默认配置...`);
                }
                return await this.loadDefaultCharacter();
            }
            
            // 如果已经是当前诗人，直接返回
            if (this.currentPoetId === poetId && this.currentModel) {
                console.log(`诗人 ${poetId} 已经是当前角色`);
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(100, `诗人 ${poetId} 切换完成`);
                    setTimeout(() => {
                        this.progressManager.hide();
                    }, 500);
                }
                return true;
            }
            
            // 显示加载状态
            this.showLoadingState(poetId);
            
            // 预加载新模型（在清除当前模型之前）
            if (!externalProgressControl) {
                this.progressManager.updateProgress(30, `预加载诗人 ${poetId} 模型...`);
            }
            const newModelData = await this.preloadPoet(poetId, options);
            
            // 添加淡出效果
            if (!externalProgressControl) {
                this.progressManager.updateProgress(50, `淡出当前模型...`);
            }
            await this.fadeOutCurrentModel();
            
            // 清理旧模型
            if (!externalProgressControl) {
                this.progressManager.updateProgress(60, `清理旧模型...`);
            }
            this.clearCurrentModel();
            
            // 使用预加载的模型数据
            if (!externalProgressControl) {
                this.progressManager.updateProgress(70, `设置新模型...`);
            }
            const success = await this.setupPreloadedModel(newModelData, poetId);
            
            if (success) {
                // 设置新模型
                this.currentPoetId = poetId;
                
                // 设置诗人特定的光照
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(80, `设置诗人光照...`);
                }
                this.setupPoetLighting(poetId);
                
                // 添加淡入效果
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(90, `淡入新模型...`);
                }
                await this.fadeInCurrentModel();
                
                // 播放入场动画
                if (options.playGreeting !== false) {
                    if (!externalProgressControl) {
                        this.progressManager.updateProgress(95, `播放入场动画...`);
                    }
                    this.playGreetingAnimation();
                }
                
                console.log(`诗人 ${poetId} 切换成功`);
                
                // 触发切换完成事件
                this.dispatchSwitchEvent(poetId);
                
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(100, `诗人 ${poetId} 切换完成`);
                    setTimeout(() => {
                        this.progressManager.hide();
                    }, 1000);
                }
                
                return true;
            } else {
                console.error(`诗人 ${poetId} 模型加载失败`);
                if (!externalProgressControl) {
                    this.progressManager.updateProgress(100, `诗人 ${poetId} 切换失败`);
                    setTimeout(() => {
                        this.progressManager.hide();
                    }, 2000);
                }
                // 确保在错误时恢复透明度
                await this.fadeInCurrentModel();
                return false;
            }
            
        } catch (error) {
            console.error(`切换诗人 ${poetId} 时发生错误:`, error);
            if (!externalProgressControl) {
                this.progressManager.updateProgress(100, `切换诗人 ${poetId} 时发生错误`);
                setTimeout(() => {
                    this.progressManager.hide();
                }, 2000);
            }
            // 确保在错误时恢复透明度
            await this.fadeInCurrentModel();
            // 发生错误时加载占位符默认角色，避免场景中无角色
            try {
                await this.loadDefaultCharacter();
                console.warn(`已回退为默认占位符角色（${poetId} 加载失败）`);
            } catch (fallbackErr) {
                console.error('加载默认占位符角色失败:', fallbackErr);
            }
            return false;
        } finally {
            this.hideLoadingState();
        }
    }

    /**
     * 加载诗人模型
     * @param {string} poetId - 诗人ID
     * @param {Object} options - 加载选项
     */
    async loadPoetModel(poetId, options = {}) {
        try {
            // 检查缓存
            if (this.modelCache.has(poetId)) {
                console.log(`从缓存加载诗人 ${poetId} 模型`);
                const cachedData = this.modelCache.get(poetId); // { modelData, config }
                return this.setupModel(cachedData, poetId);
            }

            // 检查是否正在加载
            if (this.loadingPromises.has(poetId)) {
                console.log(`等待诗人 ${poetId} 模型加载完成`);
                const pending = await this.loadingPromises.get(poetId); // { modelData, config }
                return this.setupModel(pending, poetId);
            }

            // 获取模型配置
            const config = getPoetModelConfig(poetId);
            if (!config) {
                throw new Error(`诗人 ${poetId} 的模型配置不存在`);
            }

            // 如果配置指定使用默认模型或没有模型URL，则使用默认模型
            let effectiveConfig = config;
            if (config.useDefault || !config.modelUrl) {
                console.log(`诗人 ${poetId} 使用默认模型`);
                const defaultConfig = getPoetModelConfig('liqingzhao');
                if (!defaultConfig || !defaultConfig.modelUrl) {
                    throw new Error('默认模型配置无效');
                }
                effectiveConfig = { ...config, modelUrl: defaultConfig.modelUrl };
            }

            // 创建加载Promise（返回数据对象），完成后再挂载
            const loadPromise = this.loadModelFromConfig(effectiveConfig, poetId); // returns { modelData, config }
            this.loadingPromises.set(poetId, loadPromise);

            const payload = await loadPromise; // { modelData, config }
            this.loadingPromises.delete(poetId);

            return this.setupModel(payload, poetId);
        } catch (error) {
            console.error(`加载诗人 ${poetId} 模型失败:`, error);
            this.loadingPromises.delete(poetId);
            return false;
        }
    }

    /**
     * 从配置加载模型
     * @param {Object} config - 模型配置
     * @param {string} poetId - 诗人ID
     */
    async loadModelFromConfig(config, poetId) {
        try {
            console.log(`开始加载诗人 ${poetId} 的3D模型:`, config.modelUrl);

            // 使用ModelLoader加载模型，但此函数仅返回数据，不直接挂载到场景
            const modelData = await this.modelLoader.loadModel(config.modelUrl, {
                scale: config.scale,
                position: new THREE.Vector3(config.position.x, config.position.y, config.position.z),
                rotation: new THREE.Euler(config.rotation.x, config.rotation.y, config.rotation.z),
                castShadow: true,
                receiveShadow: true,
                onProgress: (progress) => {
                    this.updateLoadingProgress(poetId, progress);
                }
            });

            // 应用诗人特定的材质设置
            this.applyPoetMaterials(modelData.model, config.materials);

            // 缓存模型数据（供预加载与后续挂载使用）
            const cachedPayload = { modelData, config };
            this.modelCache.set(poetId, cachedPayload);

            // 返回数据，挂载由调用方决定
            return cachedPayload;
        } catch (error) {
            console.error(`从配置加载诗人 ${poetId} 模型失败:`, error);
            throw error;
        }
    }

    /**
     * 设置模型到场景中
     * @param {Object} data - 模型数据
     * @param {string} poetId - 诗人ID
     */
    setupModel(data, poetId) {
        try {
            const { modelData, config } = data;
            
            // 添加模型到角色组
            this.characterGroup.add(modelData.model);
            this.currentModel = modelData.model;
            
            // 设置动画控制器
            if (modelData.animations && modelData.animations.length > 0) {
                this.currentAnimationController = new AnimationController(modelData, this.clock);
                
                // 输出可用动画
                const availableAnimations = this.currentAnimationController.getAnimationNames();
                console.log(`诗人 ${poetId} 可用动画:`, availableAnimations);
            }
            
            // 设置模型位置和旋转
            // 使用场景配置的角色生成位置，而不是模型配置中的位置
            const spawnPoint = this.getCharacterSpawnPoint();
            this.currentModel.position.copy(new THREE.Vector3(spawnPoint.x, spawnPoint.y, spawnPoint.z));
            this.currentModel.rotation.copy(new THREE.Euler(config.rotation.x, config.rotation.y, config.rotation.z));
            this.currentModel.scale.setScalar(config.scale);
            
            console.log(`诗人 ${poetId} 模型设置完成`);
            return true;
            
        } catch (error) {
            console.error(`设置诗人 ${poetId} 模型失败:`, error);
            return false;
        }
    }

    /**
     * 应用诗人特定的材质设置
     * @param {THREE.Object3D} model - 模型对象
     * @param {Object} materialsConfig - 材质配置
     */
    applyPoetMaterials(model, materialsConfig) {
        if (!materialsConfig) return;
        
        model.traverse((child) => {
            if (child.isMesh && child.material) {
                const materials = Array.isArray(child.material) ? child.material : [child.material];
                
                materials.forEach(material => {
                    // 获取材质名称的小写版本用于更灵活的匹配
                    const materialName = (material.name || '').toLowerCase();
                    
                    // 应用皮肤材质设置 - 匹配包含skin、face、head等与皮肤相关的材质
                    if ((materialName.includes('skin') || materialName.includes('face') || 
                         materialName.includes('head') || materialName.includes('hair')) && 
                        materialsConfig.skin) {
                        Object.assign(material, materialsConfig.skin);
                        console.log('应用皮肤材质设置到:', material.name);
                    }
                    
                    // 应用服装材质设置
                    if (materialName.includes('cloth') || materialName.includes('clothes') || 
                        materialName.includes('outfit') || materialName.includes('cloth') ||
                        materialName.includes('dress') || materialName.includes('robe')) {
                        Object.assign(material, materialsConfig.clothing);
                        console.log('应用服装材质设置到:', material.name);
                    }
                    
                    // 对于没有明确匹配的材质，如果有头发相关的关键字，也应用皮肤材质设置
                    if (materialName.includes('hair') && materialsConfig.skin) {
                        Object.assign(material, materialsConfig.skin);
                        console.log('应用皮肤材质设置到头发:', material.name);
                    }
                    
                    // 确保材质更新
                    material.needsUpdate = true;
                    
                    // 修复秃头问题：确保材质正确渲染，不透明且深度测试正常
                    material.transparent = false;
                    material.side = THREE.FrontSide;
                    material.depthWrite = true;
                    material.depthTest = true;
                });
            }
        });
    }

    /**
     * 设置诗人特定的光照
     * @param {string} poetId - 诗人ID
     */
    setupPoetLighting(poetId) {
        if (!this.options.enableLighting) return;
        
        const config = getPoetModelConfig(poetId);
        if (!config || !config.lighting) return;
        
        // 清理现有光照
        this.lightingGroup.clear();
        
        const lighting = config.lighting;
        
        // 环境光
        const ambientLight = new THREE.AmbientLight(0x404040, lighting.ambientIntensity);
        this.lightingGroup.add(ambientLight);
        
        // 主光源
        const directionalLight = new THREE.DirectionalLight(0xffffff, lighting.directionalIntensity);
        directionalLight.position.set(2, 4, 3);
        directionalLight.castShadow = true;
        directionalLight.shadow.mapSize.width = 2048;
        directionalLight.shadow.mapSize.height = 2048;
        directionalLight.shadow.camera.near = 0.5;
        directionalLight.shadow.camera.far = 50;
        directionalLight.shadow.intensity = lighting.shadowIntensity;
        this.lightingGroup.add(directionalLight);
        
        // 补光
        const fillLight = new THREE.DirectionalLight(0x87CEEB, 0.3);
        fillLight.position.set(-2, 2, -3);
        this.lightingGroup.add(fillLight);
        
        console.log(`诗人 ${poetId} 光照设置完成`);
    }

    /**
     * 播放动画
     * @param {string} animationName - 动画名称
     * @param {Object} options - 播放选项
     */
    playAnimation(animationName, options = {}) {
        if (!this.currentAnimationController) {
            console.warn('没有可用的动画控制器');
            return;
        }
        
        // 获取当前诗人的动画映射
        const config = getPoetModelConfig(this.currentPoetId);
        const mappedAnimation = config?.animations?.[animationName] || animationName;
        
        this.currentAnimationController.playAnimation(mappedAnimation, options);
    }

    /**
     * 播放问候动画
     */
    playGreetingAnimation() {
        this.playAnimation('greeting', {
            loop: false,
            onFinished: () => {
                this.playAnimation('idle');
            }
        });
    }

    /**
     * 开始说话动画
     */
    startSpeaking() {
        console.log('诗人开始说话，播放说话动画');
        this.playAnimation('speaking', {
            loop: true,
            fadeTime: 0.3
        });
    }

    /**
     * 停止说话动画
     */
    stopSpeaking() {
        console.log('诗人停止说话，切换到空闲动画');
        this.playAnimation('idle', {
            loop: true,
            fadeTime: 0.5
        });
    }

    /**
     * 播放思考动画
     */
    playThinkingAnimation() {
        console.log('诗人思考中，播放思考动画');
        this.playAnimation('thinking', {
            loop: true,
            fadeTime: 0.3
        });
    }

    /**
     * 播放点头动画
     */
    playNodAnimation() {
        console.log('诗人点头确认');
        this.playAnimation('nod', {
            loop: false,
            onFinished: () => {
                this.playAnimation('idle');
            }
        });
    }

    /**
     * 播放摇头动画
     */
    playShakeHeadAnimation() {
        console.log('诗人摇头');
        this.playAnimation('shake_head', {
            loop: false,
            onFinished: () => {
                this.playAnimation('idle');
            }
        });
    }

    /**
     * 预加载诗人模型
     * @param {Array} poetIds - 要预加载的诗人ID数组
     */
    async preloadPoetModels(poetIds = []) {
        if (!this.options.enablePreloading) return;
        
        console.log('开始预加载诗人模型:', poetIds);
        
        const preloadPromises = poetIds.map(async (poetId) => {
            try {
                if (!this.modelCache.has(poetId) && hasPoetModel(poetId)) {
                    await this.loadPoetModel(poetId);
                    console.log(`诗人 ${poetId} 预加载完成`);
                }
            } catch (error) {
                console.warn(`诗人 ${poetId} 预加载失败:`, error);
            }
        });
        
        await Promise.allSettled(preloadPromises);
        console.log('诗人模型预加载完成');
    }

    /**
     * 加载默认角色
     */
    async loadDefaultCharacter() {
        // Supersplat 场景下跳过占位符加载，交由 ImmersiveSceneManager 统一处理
        if (window.immersiveSceneManager && window.immersiveSceneManager.currentScene && window.immersiveSceneManager.currentScene.type === SCENE_TYPES.SUPERSPLAT_VIEWER) {
            console.log('Supersplat 场景下跳过默认占位符角色加载');
            return false;
        }
        console.log('加载默认角色');
        
        // 创建一个简单的占位符角色
        const geometry = new THREE.CapsuleGeometry(0.5, 1.5, 4, 8);
        const material = new THREE.MeshStandardMaterial({ 
            color: 0x8B4513,
            roughness: 0.8,
            metalness: 0.2
        });
        
        const defaultCharacter = new THREE.Mesh(geometry, material);
        
        // 使用场景配置的角色生成位置，而不是硬编码位置
        // 这样可以确保角色出现在VR用户前方正确位置
        const spawnPoint = this.getCharacterSpawnPoint();
        defaultCharacter.position.set(spawnPoint.x, spawnPoint.y + 0.75, spawnPoint.z);
        
        defaultCharacter.castShadow = true;
        defaultCharacter.receiveShadow = true;
        
        this.characterGroup.add(defaultCharacter);
        this.currentModel = defaultCharacter;
        this.currentPoetId = 'default';
        
        return true;
    }

    /**
     * 获取角色生成位置
     * 从场景配置或使用默认值
     */
    getCharacterSpawnPoint() {
        // 尝试从全局场景管理器获取当前场景的角色生成点
        if (window.immersiveSceneManager && window.immersiveSceneManager.currentScene) {
            const spawnPoint = window.immersiveSceneManager.currentScene.characterSpawnPoint;
            if (spawnPoint) {
                console.log('使用场景配置的角色生成位置:', spawnPoint);
                return spawnPoint;
            }
        }
        
        // 默认位置：用户前方3米
        const defaultSpawnPoint = { x: 0, y: 0, z: -3 };
        console.log('使用默认角色生成位置:', defaultSpawnPoint);
        return defaultSpawnPoint;
    }

    /**
     * 清理当前模型
     */
    clearCurrentModel() {
        if (this.currentModel) {
            this.characterGroup.remove(this.currentModel);
            this.currentModel = null;
        }
        
        if (this.currentAnimationController) {
            this.currentAnimationController.dispose();
            this.currentAnimationController = null;
        }
    }

    /**
     * 显示加载状态
     * @param {string} poetId - 诗人ID
     */
    showLoadingState(poetId) {
        console.log(`显示诗人 ${poetId} 加载状态`);
        // 可以在这里添加UI加载指示器
    }

    /**
     * 隐藏加载状态
     */
    hideLoadingState() {
        console.log('隐藏加载状态');
        // 可以在这里隐藏UI加载指示器
    }

    /**
     * 更新加载进度
     * @param {string} poetId - 诗人ID
     * @param {Object} progress - 进度信息
     */
    updateLoadingProgress(poetId, progress) {
        const percentage = Math.round((progress.loaded / progress.total) * 100);
        console.log(`诗人 ${poetId} 加载进度: ${percentage}%`);
        
        // 使用进度管理器更新UI进度
        // 模型加载进度在整体进度中占40-70%的范围
        const modelProgress = 40 + (percentage * 0.3); // 40%到70%
        this.progressManager.updateProgress(modelProgress, `加载诗人 ${poetId} 模型... (${percentage}%)`);
    }

    /**
     * 触发切换完成事件
     * @param {string} poetId - 诗人ID
     */
    dispatchSwitchEvent(poetId) {
        const event = new CustomEvent('poet3d:switched', {
            detail: { poetId, character: this }
        });
        window.dispatchEvent(event);
    }

    /**
     * 更新动画（在渲染循环中调用）
     */
    update() {
        if (this.currentAnimationController) {
            this.currentAnimationController.update();
        }
    }

    /**
     * 获取当前诗人ID
     */
    getCurrentPoetId() {
        return this.currentPoetId;
    }

    /**
     * 获取当前模型
     */
    getCurrentModel() {
        return this.currentModel;
    }

    /**
     * 预加载诗人模型（用于平滑切换）
     * @param {string} poetId - 诗人ID
     * @param {Object} options - 加载选项
     */
    async preloadPoet(poetId, options = {}) {
        try {
            // 检查缓存
            if (this.modelCache.has(poetId)) {
                console.log(`从缓存获取诗人 ${poetId} 模型`);
                return this.modelCache.get(poetId); // { modelData, config }
            }

            // 获取模型配置
            const config = getPoetModelConfig(poetId);
            if (!config) {
                throw new Error(`诗人 ${poetId} 的模型配置不存在`);
            }

            // 加载模型数据（返回 { modelData, config }）
            const payload = await this.loadModelFromConfig(config, poetId);
            return payload;
        } catch (error) {
            console.error(`预加载诗人 ${poetId} 模型失败:`, error);
            throw error;
        }
    }

    /**
     * 设置预加载的模型
     * @param {Object} data - 预加载的模型数据
     * @param {string} poetId - 诗人ID
     */
    async setupPreloadedModel(data, poetId) {
        try {
            const { modelData, config } = data;
            
            // 添加模型到角色组
            this.characterGroup.add(modelData.model);
            this.currentModel = modelData.model;
            
            // 设置动画控制器
            if (modelData.animations && modelData.animations.length > 0) {
                this.currentAnimationController = new AnimationController(modelData, this.clock);
                
                // 输出可用动画
                const availableAnimations = this.currentAnimationController.getAnimationNames();
                console.log(`诗人 ${poetId} 可用动画:`, availableAnimations);
            }
            
            // 设置模型位置和旋转
            this.currentModel.position.copy(new THREE.Vector3(config.position.x, config.position.y, config.position.z));
            this.currentModel.rotation.copy(new THREE.Euler(config.rotation.x, config.rotation.y, config.rotation.z));
            this.currentModel.scale.setScalar(config.scale);
            
            // 初始设置为透明（用于淡入效果）
            this.setModelOpacity(0);
            
            console.log(`诗人 ${poetId} 预加载模型设置完成`);
            return true;
            
        } catch (error) {
            console.error(`设置预加载诗人 ${poetId} 模型失败:`, error);
            return false;
        }
    }

    /**
     * 淡出当前模型
     */
    async fadeOutCurrentModel() {
        if (!this.currentModel) return;
        
        return new Promise((resolve) => {
            const duration = 300; // 300ms
            const startTime = Date.now();
            
            const animate = () => {
                const elapsed = Date.now() - startTime;
                const progress = Math.min(elapsed / duration, 1);
                const opacity = 1 - progress;
                
                this.setModelOpacity(opacity);
                
                if (progress < 1) {
                    requestAnimationFrame(animate);
                } else {
                    resolve();
                }
            };
            
            animate();
        });
    }

    /**
     * 淡入当前模型
     */
    async fadeInCurrentModel() {
        if (!this.currentModel) return;
        
        return new Promise((resolve) => {
            const duration = 300; // 300ms
            const startTime = Date.now();
            
            const animate = () => {
                const elapsed = Date.now() - startTime;
                const progress = Math.min(elapsed / duration, 1);
                const opacity = progress;
                
                this.setModelOpacity(opacity);
                
                if (progress < 1) {
                    requestAnimationFrame(animate);
                } else {
                    resolve();
                }
            };
            
            animate();
        });
    }

    /**
     * 设置模型透明度
     * @param {number} opacity - 透明度值 (0-1)
     */
    setModelOpacity(opacity) {
        if (!this.currentModel) return;
        
        this.currentModel.traverse((child) => {
            if (child.isMesh && child.material) {
                const materials = Array.isArray(child.material) ? child.material : [child.material];
                
                materials.forEach(material => {
                    // 确保材质支持透明度
                    material.transparent = true;
                    material.opacity = opacity;
                    material.needsUpdate = true;
                });
            }
        });
    }

    /**
     * 清理资源
     */
    dispose() {
        // 清理当前模型
        this.clearCurrentModel();
        
        // 清理缓存
        this.modelCache.clear();
        this.loadingPromises.clear();
        
        // 移除场景元素
        this.scene.remove(this.characterGroup);
        this.scene.remove(this.lightingGroup);
        
        console.log('诗人3D角色管理器已清理');
    }
}